package com.xayq.orap.oauth.authorize;


import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.xayq.orap.model.AccessToken;
import com.xayq.orap.model.ClientDetails;
import com.xayq.orap.oauth.MyOAuthAuthzRequest;
import com.xayq.orap.utils.CommonUtils;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

@Component
public class TokenAuthorizeHandler extends AbstractAuthorizeHandler {


    private static final Logger LOG = LoggerFactory.getLogger(TokenAuthorizeHandler.class);


    /*
    *  response token
    *
    *  If it is the first logged or first approval , always return newly AccessToken
    *  Always exclude refresh_token
    *
    * */
    @Override
    protected void handleResponse() throws OAuthSystemException, IOException {

        if (forceNewAccessToken()) {
            forceTokenResponse();
        } else {
            AccessToken accessToken = oAuthService.retrieveAccessToken(clientDetails(), oauthRequest.getScopes(), getUsername());

            if (accessToken.tokenExpired()) {
                expiredTokenResponse(accessToken);
            } else {
                normalTokenResponse(accessToken);
            }
        }
    }

    private void forceTokenResponse() throws OAuthSystemException {
        AccessToken accessToken = oAuthService.retrieveNewAccessToken(clientDetails(),getUsername(), oauthRequest.getScopes());
        normalTokenResponse(accessToken);
    }

    private void normalTokenResponse(AccessToken accessToken) throws OAuthSystemException {

        OAuthResponse oAuthResponse = createTokenResponse(accessToken, true);
        LOG.debug("'token' response: {}", oAuthResponse);

        CommonUtils.writeOAuthQueryResponse(response, oAuthResponse);
    }

    private void expiredTokenResponse(AccessToken accessToken) throws OAuthSystemException {
        ClientDetails clientDetails = clientDetails();
        LOG.debug("AccessToken {} is expired", accessToken);

        OAuthResponse oAuthResponse = OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
                .setError(OAuthError.ResourceResponse.EXPIRED_TOKEN)
                .setErrorDescription("access_token '" + accessToken.getToken() + "' expired")
                .setErrorUri(clientDetails.getRedirectUri())
                .buildJSONMessage();

        CommonUtils.writeOAuthJsonResponse(response, oAuthResponse);
    }

    private boolean forceNewAccessToken() {
        ClientDetails clientDetails = clientDetails();
        return userFirstApproved;
    }
    
    @Override
    public OAuthResponse validatePlus() throws OAuthSystemException {
        return null;
    }
    
}
